package com.tdam2011.grupo05.database.content;

import com.tdam2011.grupo05.database.DatabaseHelper;
import com.tdam2011.grupo05.entities.account.Account;
import com.tdam2011.grupo05.entities.contact.ContactWeb;
import com.tdam2011.grupo05.entities.logs.LogImp;
import com.tdam2011.grupo05.entities.message.MessageWeb;
import com.tdam2011.grupo05.entities.thread.ThreadWeb;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.BaseColumns;

public class TdamContentProvider extends ContentProvider {

	public static final String CONTENT_AUTHORITY = "com.tdam2011.grupo05";
	public static final Uri BASE_CONTENT_URI = Uri.parse("content://"
			+ CONTENT_AUTHORITY);

	private DatabaseHelper mHelper;

	private static final int MESSAGE = 100;
	private static final int MESSAGE_ID = 101;
	private static final String PATH_MESSAGE = "message";

	private static final int THREAD = 300;
	private static final int THREAD_ID = 301;
	private static final String PATH_THREAD = "thread";

	private static final int USER = 500;
	private static final int USER_ID = 501;
	private static final String PATH_USER = "user";

	private static final int ACCOUNT = 600;
	private static final int ACCOUNT_ID = 601;
	private static final String PATH_ACCOUNT = "account";

	private static final int LOGGER = 700;
	private static final int LOGGER_ID = 701;
	private static final String PATH_LOGGER = "logger";

	public static final String CONTENT_TYPE_MESSAGE = ContentResolver.CURSOR_DIR_BASE_TYPE
			+ "/vnd.com.tdam.message";
	public static final String CONTENT_ITEM_TYPE_MESSAGES = ContentResolver.CURSOR_ITEM_BASE_TYPE
			+ "/vnd.com.tdam.message";

	public static final String CONTENT_TYPE_THREAD = ContentResolver.CURSOR_DIR_BASE_TYPE
			+ "vnd.com.tdam.thread";

	public static final String CONTENT_ITEM_TYPE_THREAD = ContentResolver.CURSOR_ITEM_BASE_TYPE
			+ "vnd.com.tdam.thread";

	public static final String CONTENT_TYPE_USER = ContentResolver.CURSOR_DIR_BASE_TYPE
			+ "vnd.com.tdam.user";

	public static final String CONTENT_ITEM_TYPE_USER = ContentResolver.CURSOR_ITEM_BASE_TYPE
			+ "vnd.com.tdam.user";

	public static final String CONTENT_TYPE_ACCOUNT = ContentResolver.CURSOR_DIR_BASE_TYPE
			+ "vnd.com.tdam.account";

	public static final String CONTENT_ITEM_TYPE_ACCOUNT = ContentResolver.CURSOR_ITEM_BASE_TYPE
			+ "vnd.com.tdam.account";

	public static final String CONTENT_TYPE_LOGGER = ContentResolver.CURSOR_DIR_BASE_TYPE
			+ "vnd.com.tdam.logger";

	public static final String CONTENT_ITEM_TYPE_LOGGER = ContentResolver.CURSOR_ITEM_BASE_TYPE
			+ "vnd.com.tdam.logger";

	public static final Uri MESSAGE_CONTENT_URI = BASE_CONTENT_URI.buildUpon()
			.appendPath(PATH_MESSAGE).build();

	public static final Uri THREAD_CONTENT_URI = BASE_CONTENT_URI.buildUpon()
			.appendPath(PATH_THREAD).build();

	public static final Uri USER_CONTENT_URI = BASE_CONTENT_URI.buildUpon()
			.appendPath(PATH_USER).build();

	public static final Uri ACCOUNT_CONTENT_URI = BASE_CONTENT_URI.buildUpon()
			.appendPath(PATH_ACCOUNT).build();

	public static final Uri LOGGER_CONTENT_URI = BASE_CONTENT_URI.buildUpon()
			.appendPath(PATH_LOGGER).build();

	private static final UriMatcher uriMatcher = buildMatcher();

	private static UriMatcher buildMatcher() {
		UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);

		matcher.addURI(CONTENT_AUTHORITY, "message", MESSAGE);
		matcher.addURI(CONTENT_AUTHORITY, "message/*", MESSAGE_ID);
		matcher.addURI(CONTENT_AUTHORITY, "thread", THREAD);
		matcher.addURI(CONTENT_AUTHORITY, "thread/*", THREAD_ID);
		matcher.addURI(CONTENT_AUTHORITY, "user", USER);
		matcher.addURI(CONTENT_AUTHORITY, "user/*", USER_ID);
		matcher.addURI(CONTENT_AUTHORITY, "account", ACCOUNT);
		matcher.addURI(CONTENT_AUTHORITY, "account/*", ACCOUNT_ID);
		matcher.addURI(CONTENT_AUTHORITY, "logger", LOGGER);
		matcher.addURI(CONTENT_AUTHORITY, "logger/*", LOGGER_ID);

		return matcher;
	}

	@Override
	public String getType(Uri uri) {
		final int match = uriMatcher.match(uri);
		switch (match) {

		case MESSAGE:
			return CONTENT_TYPE_MESSAGE;
		case MESSAGE_ID:
			return CONTENT_ITEM_TYPE_MESSAGES;
		case THREAD:
			return CONTENT_TYPE_THREAD;
		case THREAD_ID:
			return CONTENT_ITEM_TYPE_THREAD;
		case USER:
			return CONTENT_TYPE_USER;
		case USER_ID:
			return CONTENT_ITEM_TYPE_USER;
		case ACCOUNT:
			return CONTENT_TYPE_ACCOUNT;
		case ACCOUNT_ID:
			return CONTENT_ITEM_TYPE_ACCOUNT;
		case LOGGER:
			return CONTENT_TYPE_ACCOUNT;
		case LOGGER_ID:
			return CONTENT_ITEM_TYPE_ACCOUNT;
		default:
			throw new UnsupportedOperationException("Unknown uri: " + uri);
		}
	}

	@Override
	public boolean onCreate() {
		mHelper = new DatabaseHelper(getContext());
		return true;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		SQLiteDatabase db = mHelper.getWritableDatabase();
		String finalWhere = selection;
		int count;
		String table = null;
		switch (uriMatcher.match(uri)) {

		case MESSAGE:
			table = MessageWeb.TABLE_NAME;
			break;
		case MESSAGE_ID:
			finalWhere = BaseColumns._ID + " = " + getId(uri);
			if (selection != null) {
				finalWhere = finalWhere + " AND " + selection;
			}
			table = MessageWeb.TABLE_NAME;
			break;
		case THREAD:
			table = ThreadWeb.TABLE_NAME;
			break;
		case THREAD_ID:
			finalWhere = BaseColumns._ID + " = " + getId(uri);
			if (selection != null) {
				finalWhere = finalWhere + " AND " + selection;
			}
			table = ThreadWeb.TABLE_NAME;
			break;
		case USER:
			table = ContactWeb.TABLE_NAME;
			break;
		case USER_ID:
			finalWhere = BaseColumns._ID + " = " + getId(uri);
			if (selection != null) {
				finalWhere = finalWhere + " AND " + selection;
			}
			table = ContactWeb.TABLE_NAME;
			break;
		case ACCOUNT:
			table = Account.TABLE_NAME;
			break;
		case ACCOUNT_ID:
			finalWhere = BaseColumns._ID + " = " + getId(uri);
			if (selection != null) {
				finalWhere = finalWhere + " AND " + selection;
			}
			table = Account.TABLE_NAME;
			break;
		case LOGGER:
			table = LogImp.TABLE_NAME;
			break;
		case LOGGER_ID:
			finalWhere = BaseColumns._ID + " = " + getId(uri);
			if (selection != null) {
				finalWhere = finalWhere + " AND " + selection;
			}
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		count = db.delete(table, finalWhere, selectionArgs);

		getContext().getContentResolver().notifyChange(uri, null);

		return count;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		final SQLiteDatabase db = mHelper.getWritableDatabase();
		final int match = uriMatcher.match(uri);

		switch (match) {
		case MESSAGE: {
			long _id = db.insertOrThrow(MessageWeb.TABLE_NAME, null, values);
			getContext().getContentResolver().notifyChange(uri, null);
			return buildUri(MESSAGE_CONTENT_URI, String.valueOf(_id));
		}
		case THREAD: {
			long _id = db.insertOrThrow(ThreadWeb.TABLE_NAME, null, values);
			getContext().getContentResolver().notifyChange(uri, null);
			return buildUri(THREAD_CONTENT_URI, String.valueOf(_id));
		}
		case USER: {
			long _id = db.insertOrThrow(ContactWeb.TABLE_NAME, null, values);
			getContext().getContentResolver().notifyChange(uri, null);
			return buildUri(USER_CONTENT_URI, String.valueOf(_id));
		}
		case ACCOUNT: {
			long _id = db.insertOrThrow(Account.TABLE_NAME, null, values);
			getContext().getContentResolver().notifyChange(uri, null);
			return buildUri(ACCOUNT_CONTENT_URI, String.valueOf(_id));
		}
		case LOGGER: {
			long _id = db.insertOrThrow(LogImp.TABLE_NAME, null, values);
			getContext().getContentResolver().notifyChange(uri, null);
			return buildUri(LOGGER_CONTENT_URI, String.valueOf(_id));
		}
		default: {
			throw new UnsupportedOperationException("Unknown uri: " + uri);
		}

		}
	}

	public static Uri buildUri(Uri uri, String id) {
		return uri.buildUpon().appendPath(id).build();
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {

		final int match = uriMatcher.match(uri);

		final SQLiteDatabase db = mHelper.getReadableDatabase();

		final SQLiteQueryBuilder builder = buildExpandedSelection(uri, match);
		Cursor c = builder.query(db, projection, selection, selectionArgs,
				null, null, sortOrder);
		// notificacion ante un cambio en los datos de la uri consultada
		c.setNotificationUri(getContext().getContentResolver(), uri);
		return c;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {

		SQLiteDatabase db = mHelper.getWritableDatabase();
		int count;
		String id;
		String finalWhere = null;
		switch (uriMatcher.match(uri)) {

		case MESSAGE:
			count = db.update(MessageWeb.TABLE_NAME, values, selection,
					selectionArgs);
			getContext().getContentResolver().notifyChange(uri, null);
			return count;
		case MESSAGE_ID:
			id = getId(uri);
			finalWhere = BaseColumns._ID + " = " + id;
			if (selection != null)
				finalWhere = finalWhere + " AND " + selection;

			count = db.update(MessageWeb.TABLE_NAME, values, finalWhere,
					selectionArgs);
			getContext().getContentResolver().notifyChange(uri, null);
			return count;

		case THREAD:
			count = db.update(ThreadWeb.TABLE_NAME, values, selection,
					selectionArgs);
			getContext().getContentResolver().notifyChange(uri, null);
			return count;
		case THREAD_ID:
			id = getId(uri);
			finalWhere = BaseColumns._ID + " = " + id;
			if (selection != null)
				finalWhere = finalWhere + " AND " + selection;

			count = db.update(ThreadWeb.TABLE_NAME, values, finalWhere,
					selectionArgs);
			getContext().getContentResolver().notifyChange(uri, null);
			return count;
		case USER:
			count = db.update(ContactWeb.TABLE_NAME, values, selection,
					selectionArgs);
			getContext().getContentResolver().notifyChange(uri, null);
			return count;
		case USER_ID:
			id = getId(uri);
			finalWhere = BaseColumns._ID + " = " + id;
			if (selection != null)
				finalWhere = finalWhere + " AND " + selection;

			count = db.update(ContactWeb.TABLE_NAME, values, finalWhere,
					selectionArgs);
			getContext().getContentResolver().notifyChange(uri, null);
			return count;
		case ACCOUNT:
			count = db.update(Account.TABLE_NAME, values, selection,
					selectionArgs);
			getContext().getContentResolver().notifyChange(uri, null);
			return count;
		case ACCOUNT_ID:
			id = getId(uri);
			finalWhere = BaseColumns._ID + " = " + id;
			if (selection != null)
				finalWhere = finalWhere + " AND " + selection;

			count = db.update(Account.TABLE_NAME, values, finalWhere,
					selectionArgs);
			getContext().getContentResolver().notifyChange(uri, null);
			return count;
		case LOGGER:
			count = db.update(LogImp.TABLE_NAME, values, selection,
					selectionArgs);
			getContext().getContentResolver().notifyChange(uri, null);
			return count;
		case LOGGER_ID:
			id = getId(uri);
			finalWhere = BaseColumns._ID + " = " + id;
			if (selection != null)
				finalWhere = finalWhere + " AND " + selection;

			count = db.update(LogImp.TABLE_NAME, values, finalWhere,
					selectionArgs);
			getContext().getContentResolver().notifyChange(uri, null);
			return count;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

	}

	private SQLiteQueryBuilder buildExpandedSelection(Uri uri, int match) {
		SQLiteQueryBuilder builder = new SQLiteQueryBuilder();

		String id = null;
		switch (match) {
		case MESSAGE:
			builder.setTables(MessageWeb.TABLE_NAME);
			break;

		case MESSAGE_ID:
			id = getId(uri);
			builder.setTables(MessageWeb.TABLE_NAME);
			builder.appendWhere(BaseColumns._ID + "=" + id);
			break;

		case THREAD:
			builder.setTables(ThreadWeb.TABLE_NAME);
			break;

		case THREAD_ID:
			id = getId(uri);
			builder.setTables(ThreadWeb.TABLE_NAME);
			builder.appendWhere(BaseColumns._ID + "=" + id);
			break;
		case USER:
			builder.setTables(ContactWeb.TABLE_NAME);
			break;

		case USER_ID:
			id = getId(uri);
			builder.setTables(ContactWeb.TABLE_NAME);
			builder.appendWhere(BaseColumns._ID + "=" + id);
			break;
		case ACCOUNT:
			builder.setTables(Account.TABLE_NAME);
			break;

		case ACCOUNT_ID:
			id = getId(uri);
			builder.setTables(Account.TABLE_NAME);
			builder.appendWhere(BaseColumns._ID + "=" + id);
			break;
		case LOGGER:
			builder.setTables(LogImp.TABLE_NAME);
			break;

		case LOGGER_ID:
			id = getId(uri);
			builder.setTables(LogImp.TABLE_NAME);
			builder.appendWhere(BaseColumns._ID + "=" + id);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
		return builder;
	}

	public String getId(Uri uri) {
		return uri.getPathSegments().get(1);
	}
}
